Skip to content

druntime: Move accumulatePure from core.internal.array to rt.profilegc#23408

Merged
kinke merged 8 commits into
dlang:stablefrom
QuantumSegfault:move-accumulate-pure
Jul 18, 2026
Merged

druntime: Move accumulatePure from core.internal.array to rt.profilegc#23408
kinke merged 8 commits into
dlang:stablefrom
QuantumSegfault:move-accumulate-pure

Conversation

@QuantumSegfault

Copy link
Copy Markdown
Contributor

Moves accumulatePure (which is a thin wrapper around rt.profilegc.accumulate, adding forcing purity on it) out of core.internal.array and into rt.profilegc.

This helps prevent rt.profilegc from being dragged in (and thus its module destructors) when D_ProfileGC isn't enabled, reducing the size of statically linked binaries.

See ldc-developers/ldc#5186 (comment)


This problem should be solved on master by #22859. This improvement is for 1.113.

@QuantumSegfault

Copy link
Copy Markdown
Contributor Author

@kinke
@thewilsonator

@thewilsonator

Copy link
Copy Markdown
Contributor

cc @dkorpel as you wrote the fix for master, and this PR seems to do it slightly differently to what you did (and may cause merge conflicts).

@QuantumSegfault

Copy link
Copy Markdown
Contributor Author

@kinke

This hasn't been working so far. CTFE tries to instantiate the hooks, causing weird bugs.

@QuantumSegfault

Copy link
Copy Markdown
Contributor Author

Okay, I think I coaxed it into working...still some test failures to figure out.

@kinke

kinke commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Oh right, this seems to be more trouble than expected - currently hitting an assertion in the DMD glue layer.

Using a hardcoded mangle and avoiding the externDFunc mixin stuff seems to work:

diff --git a/druntime/src/core/internal/array/utils.d b/druntime/src/core/internal/array/utils.d
index 54757c0faf..3a01e89d3e 100644
--- a/druntime/src/core/internal/array/utils.d
+++ b/druntime/src/core/internal/array/utils.d
@@ -23,13 +23,8 @@ auto gcStatsPure() nothrow pure
 
 version (D_ProfileGC)
 {
-    // Needs to be templated to emit only as needed.
-    ulong accumulatePure()(string file, int line, string funcname, string name, ulong size) @nogc nothrow pure
-    {
-        import core.internal.traits : externDFunc;
-        alias impl = externDFunc!("rt.profilegc.accumulatePure", ulong function(string file, int line, string funcname, string name, ulong size) @nogc nothrow pure);
-        return impl(file, line, funcname, name, size);
-    }
+    pragma(mangle, "_D2rt9profilegc14accumulatePureFNaNbNiAyaiQeQgmZm")
+    ulong accumulatePure(string file, int line, string funcname, string name, ulong size) @nogc nothrow pure;
 
     /**
      * TraceGC wrapper generator around the runtime hook `Hook`.

For context: v2.113's core.internal.array.utils module has an object-file dependency on rt.profilegc because of this ugly pure-faking wrapper, causing hello-world programs to be much larger than needed, since rt.profilegc with its module dtors drags in loads of stuff. E.g., +23% for wasm: ldc-developers/ldc#5186 (comment)

@thewilsonator

Copy link
Copy Markdown
Contributor

Its not #23417 perchance?

@kinke
kinke merged commit 400f45d into dlang:stable Jul 18, 2026
76 checks passed
@kinke kinke mentioned this pull request Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants